﻿// (c) Copyright Max Kazarin.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

/// <reference path='../Common/jquery-1.3.2.js' />
// <reference path='../Common/MicrosoftAjax.debug.js' />

Type.registerNamespace('jQueryNET.Controls');

jQueryNET.Controls.TreeView = function jQueryNET$Controls$TreeView(element) {
    /// <summary>
    /// This class implement TreeView control
    /// </summary>
    /// <param name='element' type='Sys.UI.DomElement' domElement='true'>
    /// DOM element the control is associated with
    /// </param>

    jQueryNET.Controls.TreeView.initializeBase(this, [element]);

    //this._element = $(this.get_element());
    this._treeElement = this._rootElement
		.addClass('treeview')
		.append('<ul></ul>')
		.find('ul');

    this._onDblNodeClickHandler = Function.eventWraper(this, this._onDblNodeClick);
    this._onNodeClickHandler = Function.eventWraper(this, this._onNodeClick);
}

jQueryNET.Controls.TreeView.createElement = function(parent) {
	/// <summary>
	/// Static method for using on client-side. Create DOM element the control
	/// associated with
	/// </summary>
	/// <param name='parent' type='Sys.UI.DomElement' domElement='true'>
	/// Parent DOM element or jQuery selector
	/// </param>

	var element =
		$(parent)
			.append('<div></div>')
			.find('div:last');

	return element.get(0);
}

function jQueryNET$Controls$TreeView$initialize() {
	/// <summary>
	/// Initialize the control
	/// </summary>

	jQueryNET.Controls.TreeView.callBaseMethod(this, 'initialize');
	//this._completedCallback = Function.createCallback(this._completed, this);
	//this._errorCallback = Function.createCallback(this._error, this)

	this._rootElement
		.bind('dblclick', this, this._onDblNodeClickHandler)
		.bind('click', this, this._onNodeClickHandler);

	this.getNodes(null);
}

function jQueryNET$Controls$TreeView$dispose() {
	/// <summary>
	/// Dispose the control
	/// </summary>

	this._rootElement
		.unbind('dblclick', this, this._onNodeDblClickHandler)
		.unbind('click', this, this._onNodeClickHandler);

	jQueryNET.Controls.TreeView.callBaseMethod(this, 'dispose');
}

function jQueryNET$Controls$TreeView$get_serviceUrl() {
	/// <value type='String'>
	/// Service url
	/// </value>

	if (arguments.length !== 0) throw Error.parameterCount();
	return this._serviceUrl;
}

function jQueryNET$Controls$TreeView$set_serviceUrl(value) {
	var e = Function._validateParams(arguments, [{ name: 'value', type: String, mayBeNull: false}]);
	if (e) throw e;
	this._serviceUrl = value;
}

function jQueryNET$Controls$TreeView$get_serviceMethod() {
	/// <value type='String'>
	/// Service method
	/// </value>

	if (arguments.length !== 0) throw Error.parameterCount();
	return this._serviceMethod;
}

function jQueryNET$Controls$TreeView$set_serviceMethod(value) {
	var e = Function._validateParams(arguments, [{ name: 'value', type: String, mayBeNull: false}]);
	if (e) throw e;
	this._serviceMethod = value;
}

function jQueryNET$Controls$TreeView$getNodes(rootNodeId) {
	/// <summary>
	/// Get nodes from service
	/// </summary>

	var e = Function._validateParams(arguments, [{ name: 'rootNodeId', type: String, mayBeNull: true}]);
	if (e) throw e;

	this._showLoading(rootNodeId);

	/*if (this._webService == null)
		this._webService = new jQueryNET.Utils.WebService(this.get_serviceUrl());

	this._webService.invoke(
		this.get_serviceMethod(),
		{ nodeId: rootNodeId },
		this._completedCallback,
		this._errorCallback);
*/
	this.receiveData({
		nodeId: rootNodeId
		},
		true);	
}
/*
function jQueryNET$Controls$TreeView$_completed(result, sender, context) {
	/// <summary>
	/// Get nodes completed handler
	/// </summary>
	
	if (!result || result.length == 0)
		return;

	var parentId = result[0].ParentId;

	context._hideLoading(parentId);
	if (result[0].Id == null) {
		context._rootElement.find('li#' + parentId + '>div>img.treeview_elbow')
			.removeClass('treeview_elbow_plus_nl')
			.removeClass('treeview_elbow_minus_nl');
		return;
	}

	Array.forEach(result, function(element, index, array) {
		this.addNode(element);
	}, context);

	if (parentId) {
		var child_element = context._rootElement.find('li#' + parentId + '>ul.treeview_node_childs');
		child_element.slideDown('slow');
	}
}

function jQueryNET$Controls$TreeView$_error(message, detail, sender, context) {
	/// <summary>
	/// Get nodes error handler
	/// </summary>

	alert('error=' + message);
}
*/

function jQueryNET$Controls$TreeView$_showLoadingLayer() {
}

function jQueryNET$Controls$TreeView$_hideLoadingLayer() {
}

function jQueryNET$Controls$TreeView$_completeReceive(data) {
	/// <summary>
	/// Get nodes completed handler
    /// </summary>
	if (!data || data.length == 0)
		return;

	var parentId = data[0].ParentId;

	this._hideLoading(parentId);
	if (data[0].Id == null) {
		this._treeElement.find('li#' + parentId + '>div>img.treeview_elbow')
			.removeClass('treeview_elbow_plus_nl')
			.removeClass('treeview_elbow_minus_nl');
		return;
	}

	Array.forEach(data, function(element, index, array) {
		this.addNode(element);
	}, this);

	if (parentId) {
		var child_element = this._treeElement.find('li#' + parentId + '>ul.treeview_node_childs');
		child_element.slideDown('slow');
	}
}

function jQueryNET$Controls$TreeView$_showLoading(parentNodeId) {
	/// <summary>
	/// Show loading layer
	/// </summary>
	
	var e = Function._validateParams(arguments, [
		{ name: 'parentNodeId', type: String, mayBeNull: true}]);
	if (e) throw e;

	var htmlNode = '<li id="loading_' + parentNodeId +
				   '" class="treeview_node"><div class="treeview_node_el unselectable">' +
				   '<span class="treeview_node_indent">';
	if (parentNodeId != null && parentNodeId != '') {
		var node = this._nodesInfo[parentNodeId];
		node.Loading = true;
		for (var index = 0; index < node.Level; index++)
			htmlNode += '<img class="treeview_icon" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>">';
	}

	htmlNode += '</span>';
	htmlNode += '<img unselectable="on" class="treeview_elbow treeview_elbow_none" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>"/>';
	htmlNode += '<img unselectable="on" class="treeview_icon treeview_elbow_loading" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>"/>';
	htmlNode += '<a tabindex="1" href="javascript:void(0)" hidefocus="on"><span unselectable="on">' + jQueryNET.Resources.Loading + '</span></a></div>';
	htmlNode += '</li>';

	if (parentNodeId != null && parentNodeId != '')
		// add nodes to parent node
		this._treeElement.find('#' + parentNodeId + '>ul').append(htmlNode).show();
	else
		// add nodes to the root node
		this._treeElement.append(htmlNode).show();
}

function jQueryNET$Controls$TreeView$_hideLoading(parentId) {
	/// <summary>
	/// Hide loading layer
	/// </summary>

	var e = Function._validateParams(arguments, [
		{ name: 'parentId', type: String, mayBeNull: true}]);
	if (e) throw e;

	if (parentId != null && parentId != '') {
		this._treeElement.find('li#loading_' + parentId).parent().empty().hide();
		this._nodesInfo[parentId].Loading = false;
	}
	else
		this._treeElement.find('li#loading_' + parentId).parent().empty();
}

function jQueryNET$Controls$TreeView$addNode(node) {
	/// <summary>
	/// Add node to parent node treeview
	/// </summary>

	var e = Function._validateParams(arguments, [
		{ name: 'node', type: Object, mayBeNull: false}]);
	if (e) throw e;

	var element = this._treeElement;
	node.Level = 0;

	if (node.ParentId != null && node.ParentId != '') {
		element = this._treeElement.find('li#' + node.ParentId + '>ul.treeview_node_childs');
		node.Level = this._nodesInfo[node.ParentId].Level + 1
	}

	var htmlNode = '<li id="' + node.Id + '" class="treeview_node"><div class="treeview_node_el unselectable">' +
				   '<span class="treeview_node_indent">';
	for (var index = 0; index < node.Level; index++)
		htmlNode += '<img class="treeview_icon" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>">';

	htmlNode += '</span>';
	if (node.HasChildren)
		htmlNode += '<img unselectable="on" class="treeview_elbow treeview_elbow_plus_nl" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>"/>';
	else
		htmlNode += '<img unselectable="on" class="treeview_elbow treeview_elbow_none" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>"/>';
	if (node.ImageUrl)
		htmlNode += '<img unselectable="on" class="treeview_icon" src="<%=WebResource("jQueryNET.Common.Images.s.gif")%>" style="background-image:url(' + node.ImageUrl + ')"/>';
	var target = '';
	if (node.Url != 'javascript:void(0)')
	//htmlNode += '<a tabindex='1' href='javascript:void(0)' hidefocus='on' onclick='window.open(\'' + node.Url + '\',\'Content\' )'><span unselectable='on'>' + node.Text + '</span></a></div>';
		target += 'target="Content"';
	htmlNode += '<a tabindex="1" href="' + node.Url + '" ' + target + ' hidefocus="on"><span unselectable="on">' + node.Text + '</span></a></div>';
	//else
	//	htmlNode += '<a tabindex='1' href='javascript:void(0)' hidefocus='on'><span unselectable='on'>' + node.Text + '</span></a></div>';
	if (node.HasChildren)
		htmlNode += '<ul class="treeview_node_childs"></ul></li>';

	element.append(htmlNode);

	this._nodesInfo[node.Id] = node;
}

function jQueryNET$Controls$TreeView$_onNodeClick(event, sender) {
	/// <summary>
	/// Node click event handler
	/// </summary>

	var element = $(event.target);
	if (element.is('li>div>img')) {
		this._onDblNodeClick(event);
	}
}

function jQueryNET$Controls$TreeView$_onDblNodeClick(event) {
	/// <summary>
	/// Node double click event handler
	/// </summary>

	var element = $(event.target);
	if (element.is('li>div>a>span'))
		element = element.parent().parent().parent();
	else if (element.is('li>div>img'))
		element = element.parent().parent()
	else
		return;

	var node = this._nodesInfo[element.get(0).id]

	if (node && node.HasChildren && !node.Loading) {
		var elbow_element = $('li#' + node.Id + '>div>img.treeview_elbow');
		var child_element = $('li#' + node.Id + '>ul.treeview_node_childs');
		if (elbow_element.hasClass('treeview_elbow_plus_nl')) {
			elbow_element
				.removeClass('treeview_elbow_plus_nl')
				.addClass('treeview_elbow_minus_nl');
			if (child_element.children('li').size() == 0)
				this.getNodes(node.Id);
			else
				child_element.slideDown('slow');
		}
		else {
			$('li#' + node.Id + '>ul.treeview_node_childs').slideUp('slow',
				function() {
					$(this).find('li>ul.treeview_node_childs').hide()
					$('li#' + node.Id + ' img.treeview_elbow_minus_nl')
						.removeClass('treeview_elbow_minus_nl')
						.addClass('treeview_elbow_plus_nl');
				});
		}
	}
}

jQueryNET.Controls.TreeView.prototype = {
	_treeElement: null,
	
	_serviceUrl: null,
	_serviceMethod: null,
	_webService: null,
	_nodesInfo: new Array(),

	initialize: jQueryNET$Controls$TreeView$initialize,
	dispose: jQueryNET$Controls$TreeView$dispose,

	/*get_serviceUrl: jQueryNET$Controls$TreeView$get_serviceUrl,
	set_serviceUrl: jQueryNET$Controls$TreeView$set_serviceUrl,
	get_serviceMethod: jQueryNET$Controls$TreeView$get_serviceMethod,
	set_serviceMethod: jQueryNET$Controls$TreeView$set_serviceMethod,*/

	getNodes: jQueryNET$Controls$TreeView$getNodes,
	addNode: jQueryNET$Controls$TreeView$addNode,

/*
	_completed: jQueryNET$Controls$TreeView$_completed,
	_error: jQueryNET$Controls$TreeView$_error,
*/
	_showLoadingLayer: jQueryNET$Controls$TreeView$_showLoadingLayer,
	_hideLoadingLayer: jQueryNET$Controls$TreeView$_hideLoadingLayer,
	_completeReceive: jQueryNET$Controls$TreeView$_completeReceive,

	_onNodeClick: jQueryNET$Controls$TreeView$_onNodeClick,
	_onDblNodeClick: jQueryNET$Controls$TreeView$_onDblNodeClick,


	_showLoading: jQueryNET$Controls$TreeView$_showLoading,
	_hideLoading: jQueryNET$Controls$TreeView$_hideLoading
}

jQueryNET.Controls.TreeView.registerClass('jQueryNET.Controls.TreeView', jQueryNET.Controls.DataControlBase);
